package com.uduemc.biso.node.web.api.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.uduemc.biso.core.utils.JsonResult;
import com.uduemc.biso.node.core.entities.HConfig;
import com.uduemc.biso.node.core.entities.SArticle;
import com.uduemc.biso.node.core.entities.SCategories;
import com.uduemc.biso.node.core.entities.SPage;
import com.uduemc.biso.node.core.entities.SProduct;
import com.uduemc.biso.node.core.entities.SSeoCategory;
import com.uduemc.biso.node.core.entities.SSeoItem;
import com.uduemc.biso.node.core.entities.SSeoPage;
import com.uduemc.biso.node.core.entities.SSeoSite;
import com.uduemc.biso.node.core.entities.SSystem;
import com.uduemc.biso.node.web.api.component.Functions;
import com.uduemc.biso.node.web.api.dto.RequestSSeoCategorySave;
import com.uduemc.biso.node.web.api.dto.RequestSSeoItemSave;
import com.uduemc.biso.node.web.api.dto.RequestSSeoPageSave;
import com.uduemc.biso.node.web.api.dto.RequestSSeoSiteSave;
import com.uduemc.biso.node.web.api.service.ArticleService;
import com.uduemc.biso.node.web.api.service.CategoryService;
import com.uduemc.biso.node.web.api.service.HostService;
import com.uduemc.biso.node.web.api.service.PageService;
import com.uduemc.biso.node.web.api.service.ProductService;
import com.uduemc.biso.node.web.api.service.SConfigService;
import com.uduemc.biso.node.web.api.service.SeoService;
import com.uduemc.biso.node.web.api.service.SystemService;
import com.uduemc.biso.node.web.api.service.WebSiteService;

import cn.hutool.core.util.StrUtil;

@RestController
@RequestMapping("/api/seo")
public class SeoController {

	private final Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private SeoService seoServiceImpl;

	@Autowired
	private PageService pageServiceImpl;

	@Autowired
	private SConfigService sConfigServiceImpl;

	@Autowired
	private CategoryService categoryServiceImpl;

	@Autowired
	private Functions functions;

	@Autowired
	private SystemService systemServiceImpl;

	@Autowired
	private ArticleService articleServiceImpl;

	@Autowired
	private ProductService productServiceImpl;

	@Autowired
	private WebSiteService webSiteServiceImpl;

	@Autowired
	private HostService hostServiceImpl;

	/**
	 * 通过传入的参数 status 修改 host的 robots 状态!
	 * 
	 * @return
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	@PostMapping("/robots/update-status")
	public JsonResult updateCurrentRobotsStatus(@RequestParam("status") short status)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		boolean bool = hostServiceImpl.updateCurrentRobotStatus(status);
		if (!bool) {
			return JsonResult.assistance();
		}
		Map<String, String> resultMap = new HashMap<>();
		resultMap.put("status", String.valueOf(status));
		return JsonResult.messageSuccess("保存成功！", resultMap);
	}

	/**
	 * 通过传入的参数 status 修改 robots 的内容!
	 * 
	 * @return
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	@PostMapping("/robots/update")
	public JsonResult updateCurrentRobots(@RequestParam("robots") String robots)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		boolean bool = hostServiceImpl.updateCurrentRobots(robots);
		if (!bool) {
			return JsonResult.assistance();
		}
		return JsonResult.messageSuccess("保存成功！");
	}

	/**
	 * 通过传入的参数 ismap 对其主机配置信息中的 h_config.isMap
	 * 
	 * @param requestHostBaseInfo
	 * @param errors
	 * @return
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	@PostMapping("/save-hconfig-ismap")
	public JsonResult savehconfigismap(@RequestParam("ismap") short ismap)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		HConfig hConfig = hostServiceImpl.getCurrentHostConfig();
		hConfig.setIsMap(ismap);
		HConfig updateHostConfig = hostServiceImpl.updateHostConfig(hConfig);
		return JsonResult.messageSuccess("更新成功！", updateHostConfig);
	}

	/**
	 * 通过传入的参数 sitemapxml 对其主机配置信息中的 h_config.sitemapxml
	 * 
	 * @param requestHostBaseInfo
	 * @param errors
	 * @return
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	@PostMapping("/save-hconfig-sitemapxml")
	public JsonResult savehconfigsitemapxml(@RequestParam("sitemapxml") String sitemapxml)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		HConfig hConfig = hostServiceImpl.getCurrentHostConfig();
		hConfig.setSitemapxml(sitemapxml);
		HConfig updateHostConfig = hostServiceImpl.updateHostConfig(hConfig);
		return JsonResult.messageSuccess("更新成功！", updateHostConfig);
	}

	@PostMapping("/seosite")
	public JsonResult seoSite(@RequestParam("site_seo") short site_seo)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		if (site_seo < 0 || site_seo > 1) {
			logger.info("site_seo 异常");
			return JsonResult.illegal();
		}
		SSeoSite currentInfo = seoServiceImpl.getInfoBySiteSeo(site_seo);
		return JsonResult.ok(currentInfo);
	}

	@PostMapping("/seosite/save")
	public JsonResult seoSiteSave(@Valid @RequestBody RequestSSeoSiteSave requestSSeoSiteSave, BindingResult errors)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		boolean bool = false;
		if (requestSSeoSiteSave.getSiteSeo() == (short) 0) {
			if (requestSSeoSiteSave.getSeoSite().getSiteId().longValue() != 0L) {
				bool = true;
			}
		} else if (requestSSeoSiteSave.getSiteSeo() == (short) 1) {
			if (requestSSeoSiteSave.getSeoSite().getSiteId().longValue() == 0L) {
				bool = true;
			}
		}
		if (!bool) {
			logger.error("requestSSeoSiteSave 数据验证不通过： " + requestSSeoSiteSave.toString());
			return JsonResult.illegal();
		}
		// 是否存在这个 seoSite 数据
		if (!functions.validData(requestSSeoSiteSave.getSeoSite().getHostId(),
				requestSSeoSiteSave.getSeoSite().getSiteId())) {
			logger.error("validData 数据匹配不通过");
			return JsonResult.illegal();
		}
		SSeoSite seoSite = requestSSeoSiteSave.getSeoSite();
		String title = seoSite.getTitle();
		String keywords = seoSite.getKeywords();
		String description = seoSite.getDescription();
		if (StrUtil.length(title) > 1000) {
			return JsonResult.messageError("SEO标题长度不能超过1000");
		}
		if (StrUtil.length(keywords) > 1000) {
			return JsonResult.messageError("SEO关键字长度不能超过1000");
		}
		if (StrUtil.length(description) > 5000) {
			return JsonResult.messageError("SEO描述长度不能超过5000");
		}
		// 首先修改 s_config
		boolean changeSiteSeo = sConfigServiceImpl.changeSiteSeo(requestSSeoSiteSave.getSiteSeo());
		if (!changeSiteSeo) {
			logger.error("changeSiteSeo 修改数据不通过！");
			return JsonResult.illegal();
		}
		// 修改 seo 信息
		SSeoSite updateSeoSite = seoServiceImpl.updateSeoSite(seoSite);
		Long siteId = updateSeoSite.getSiteId();
		if (siteId == null || siteId.longValue() < 1) {
			webSiteServiceImpl.cacheCurrentHostClear();
		} else {
			webSiteServiceImpl.cacheClearByHostSiteId(updateSeoSite.getHostId(), siteId);
		}

		return JsonResult.messageSuccess(updateSeoSite);
	}

	/**
	 * 获取页面SEO数据如果沒有则直接创建后返回
	 * 
	 * @param pageId
	 * @return
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	@PostMapping("/seopage/c-info")
	public JsonResult seoPageCInfo(@RequestParam("pageId") long pageId)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		// 首先验证 pageId
		if (pageId < 1) {
			return JsonResult.illegal();
		}
		SPage sPage = pageServiceImpl.getCurrentInfoById(pageId);
		if (sPage == null) {
			return JsonResult.illegal();
		}
		SSeoPage sSeoPage = seoServiceImpl.getCurrentSeoPageInfoByPageIdAndNoDataCreate(pageId);
		if (sSeoPage == null) {
			return JsonResult.assistance();
		}
		return JsonResult.ok(RequestSSeoPageSave.getRequestSSeoPageSave(sSeoPage, sPage));
	}

	/**
	 * 保存 page 的 SEO 信息
	 * 
	 * @return
	 * @throws IOException
	 * @throws JsonProcessingException
	 * @throws JsonMappingException
	 * @throws JsonParseException
	 */
	@PostMapping("/seopage/save")
	public JsonResult seoPageSave(@Valid @RequestBody RequestSSeoPageSave requestSSeoPageSave, BindingResult errors)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		if (errors.hasErrors()) {
			for (FieldError fieldError : errors.getFieldErrors()) {
				String defaultMessage = fieldError.getDefaultMessage();
				String field = fieldError.getField();
				logger.info("field: " + field + " defaultMessage: " + defaultMessage);
				return JsonResult.messageError(field + " " + defaultMessage);
			}
		}
		SSeoPage sSeoPage = seoServiceImpl
				.getCurrentSeoPageInfoByPageIdAndNoDataCreate(requestSSeoPageSave.getPageId());
		if (sSeoPage == null) {
			return JsonResult.illegal();
		}
		sSeoPage.setTitle(requestSSeoPageSave.getTitle()).setKeywords(requestSSeoPageSave.getKeywords())
				.setDescription(requestSSeoPageSave.getDescription());
		SSeoPage data = seoServiceImpl.updateSeoPage(sSeoPage);
		if (data == null) {
			return JsonResult.assistance();
		}
		webSiteServiceImpl.cacheClearByPageId(requestSSeoPageSave.getPageId());
		return JsonResult.messageSuccess("保存成功", RequestSSeoPageSave.getRequestSSeoPageSave(data));
	}

	/**
	 * 通过 systemId、categoryId 获取 数据，如果 SSeoCategory 数据不存在则会创建该数据
	 * 
	 * @param systemId
	 * @param categoryId
	 * @return
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	@PostMapping("/seocategory/c-info")
	public JsonResult seoCateCInfo(@RequestParam("systemId") long systemId, @RequestParam("categoryId") long categoryId)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		if (systemId < 1 || categoryId < 1) {
			return JsonResult.illegal();
		}
		// 通过 systemId、categoryId 获取分类数据
		SCategories sCategories = categoryServiceImpl.getCurrentBySystemIdAndId(systemId, categoryId);
		if (sCategories == null) {
			return JsonResult.illegal();
		}
		SSeoCategory sSeoCategory = seoServiceImpl.getCurrentSeoCategoryInfoBySystemCategoryIdAndNoDataCreate(systemId,
				categoryId);
		if (sSeoCategory == null) {
			return JsonResult.assistance();
		}
		return JsonResult.ok(RequestSSeoCategorySave.getRequestSSeoCategorySave(sSeoCategory, sCategories));
	}

	@PostMapping("/seocategory/save")
	public JsonResult seocategorySave(@Valid @RequestBody RequestSSeoCategorySave requestSSeoCategorySave,
			BindingResult errors)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		if (errors.hasErrors()) {
			for (FieldError fieldError : errors.getFieldErrors()) {
				String defaultMessage = fieldError.getDefaultMessage();
				String field = fieldError.getField();
				logger.info("field: " + field + " defaultMessage: " + defaultMessage);
				return JsonResult.messageError(field + " " + defaultMessage);
			}
		}
		SSeoCategory sSeoCategory = seoServiceImpl.getCurrentSeoCategoryInfoBySystemCategoryIdAndNoDataCreate(
				requestSSeoCategorySave.getSystemid(), requestSSeoCategorySave.getCategoryId());
		if (sSeoCategory == null) {
			return JsonResult.illegal();
		}
		sSeoCategory.setTitle(requestSSeoCategorySave.getTitle()).setKeywords(requestSSeoCategorySave.getKeywords())
				.setDescription(requestSSeoCategorySave.getDescription());
		SSeoCategory data = seoServiceImpl.updateSeoCategory(sSeoCategory);
		return JsonResult.messageSuccess("保存成功", RequestSSeoCategorySave.getRequestSSeoCategorySave(data));
	}

	/**
	 * 通过传入过来的 systemId以及 itemId 获取有关这两个参数的 SSeoItem 数数
	 * 
	 * @param systemId
	 * @param itemId
	 * @return
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	@PostMapping("/seoitem/c-info")
	public JsonResult seoItemCInfo(@RequestParam("systemId") long systemId, @RequestParam("itemId") long itemId)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		if (systemId < 1 || itemId < 1) {
			return JsonResult.illegal();
		}
		// 通过 systemId 获取系统数据
		SSystem sSystem = systemServiceImpl.getCurrentInfoById(systemId);
		if (sSystem == null) {
			return JsonResult.illegal();
		}
		String itemName = null;
		if (sSystem.getSystemTypeId().longValue() == 1 || sSystem.getSystemTypeId().longValue() == 2) {
			// 文章系统
			// 获取 itemId 的名称
			SArticle sArticle = articleServiceImpl.getCurrentInfoById(itemId);
			if (sArticle == null || sArticle.getSystemId().longValue() != systemId) {
				return JsonResult.illegal();
			}
			itemName = sArticle.getTitle();
		} else if (sSystem.getSystemTypeId().longValue() == 3) {
			SProduct sProduct = productServiceImpl.getCurrentSProductById(itemId);
			if (sProduct == null || sProduct.getSystemId().longValue() != systemId) {
				return JsonResult.illegal();
			}
			itemName = sProduct.getTitle();
		} else {
			return JsonResult.illegal();
		}
		// 获取 systemId、itemId 的 SSeoItem 数据
		SSeoItem sSeoItem = seoServiceImpl.getCurrentSSeoItemInfoBySystemItemIdAndNoDataCreate(systemId, itemId);
		if (sSeoItem == null) {
			return JsonResult.illegal();
		}

		return JsonResult.ok(RequestSSeoItemSave.getRequestSSeoItemSave(sSeoItem, itemName));
	}

	@PostMapping("/seoitem/save")
	public JsonResult seoitemSave(@Valid @RequestBody RequestSSeoItemSave requestSSeoItemSave, BindingResult errors)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		if (errors.hasErrors()) {
			for (FieldError fieldError : errors.getFieldErrors()) {
				String defaultMessage = fieldError.getDefaultMessage();
				String field = fieldError.getField();
				logger.info("field: " + field + " defaultMessage: " + defaultMessage);
				return JsonResult.messageError(field + " " + defaultMessage);
			}
		}

		// 通过 systemId 获取系统数据
		SSystem sSystem = systemServiceImpl.getCurrentInfoById(requestSSeoItemSave.getSystemId());
		if (sSystem == null) {
			return JsonResult.illegal();
		}
		if (sSystem.getSystemTypeId().longValue() == 1 || sSystem.getSystemTypeId().longValue() == 2) {
			// 文章系统
			// 获取 itemId 的名称
			SArticle sArticle = articleServiceImpl.getCurrentInfoById(requestSSeoItemSave.getItemId());
			if (sArticle == null
					|| sArticle.getSystemId().longValue() != requestSSeoItemSave.getSystemId().longValue()) {
				return JsonResult.illegal();
			}
		} else if (sSystem.getSystemTypeId().longValue() == 3) {
			SProduct sProduct = productServiceImpl.getCurrentSProductById(requestSSeoItemSave.getItemId());
			if (sProduct == null
					|| sProduct.getSystemId().longValue() != requestSSeoItemSave.getSystemId().longValue()) {
				return JsonResult.illegal();
			}
		} else {
			return JsonResult.illegal();
		}

		// 获取 systemId、itemId 的 SSeoItem 数据
		SSeoItem sSeoItem = seoServiceImpl.getCurrentSSeoItemInfoBySystemItemIdAndNoDataCreate(
				requestSSeoItemSave.getSystemId(), requestSSeoItemSave.getItemId());
		if (sSeoItem == null) {
			return JsonResult.illegal();
		}
		sSeoItem.setTitle(requestSSeoItemSave.getTitle()).setKeywords(requestSSeoItemSave.getKeywords())
				.setDescription(requestSSeoItemSave.getDescription());
		SSeoItem data = seoServiceImpl.updateSeoItem(sSeoItem);
		return JsonResult.messageSuccess("保存成功", RequestSSeoItemSave.getRequestSSeoItemSave(data));
	}

}
